#include <algorithm>
#include <iostream>
#include <cmath>
#include <vector>
#include <fstream>
#include "Splines.h"

using namespace std;

// 目标函数
double f(double x) {
    return 1.0 / (1 + x * x);
}

// 目标函数的一阶导数
double df1(double x) {
    return -2 * x / ((1 + x * x) * (1 + x * x));
}

// 目标函数的二阶导数
double df2(double x) {
    return 2 * (3 * x * x - 1) / ((1 + x * x) * (1 + x * x) * (1 + x * x));
}

int main(int argc, char* argv[]) {
    cout << "CD:" << endl;

    // 定义用于检查点和误差计算的变量
    vector<double> checkPoints = {-3.5, -3, -0.5, 0.5, 3, 3.5};
    double Es; // 误差

    // 第一组数据：t_i = -6 + i, i = 1,...,11
    int n = 10;
    vector<double> x1, y1;
    for (int i = 0; i <= n; i++) {
        x1.push_back(-5.0 + i);
        y1.push_back(f(x1.back()));
    }
    Bspline spline1(x1, y1);

    // 输出到C1.txt
    ofstream C1("QC1.txt");
    C1 << "t_i = -6 + i, i = 1,...,11" << endl;
    vector<string> methods = {"线性插值：", "二次样条", "完全三次样条：", "D2三次样条：", "自然三次样条："};

    for (int m = 0; m < methods.size(); m++) {
        C1 << methods[m] << endl;
        for (double xx = -5; xx <= 5; xx += 0.001) {
            switch (m) {
                case 0:
                    C1 << spline1.S1(xx) << " ";
                    break;
                case 1:
                    C1 << spline1.S2(f(-5), f(5), xx) << " ";
                    break;
                default:
                    C1 << spline1.S3(m - 1, m == 2 ? df1(-5) : m == 3 ? df2(-5) : 0, m == 2 ? df1(5) : m == 3 ? df2(5) : 0, xx) << " ";
                    break;
            }
        }
        C1 << endl;
    }
    C1.close();

    // 第二组数据：t_i = i - 11/2, i = 1,...,10
    n = 9;
    vector<double> x2, y2;
    for (int i = 0; i <= n; i++) {
        x2.push_back(-4.5 + i);
        y2.push_back(f(x2.back()));
    }
    Bspline spline2(x2, y2);

    // 输出到C2.txt
    ofstream C2("QC2.txt");
    C2 << "t_i = i - 11/2, i = 1,...,10" << endl;
    for (int m = 0; m < methods.size(); m++) {
        C2 << methods[m] << endl;
        for (double xx = -4.5; xx <= 4.5; xx += 0.001) {
            switch (m) {
                case 0:
                    C2 << spline2.S1(xx) << " ";
                    break;
                case 1:
                    C2 << spline2.S2(f(-4.5), f(4.5), xx) << " ";
                    break;
                default:
                    C2 << spline2.S3(m - 1, m == 2 ? df1(-4.5) : m == 3 ? df2(-4.5) : 0, m == 2 ? df1(4.5) : m == 3 ? df2(4.5) : 0, xx) << " ";
                    break;
            }
        }
        C2 << endl;
    }
    C2.close();
    cout << "See QC2.txt" << endl;

    // 二次样条的误差计算
    cout << "二次样条误差：";
    for (double point : checkPoints) {
        Es = abs(spline1.S2(f(-5), f(5), point) - f(point));
        cout << Es << " ";
    }
    cout << endl;

    // 完全三次样条的误差计算
    cout << "完全三次样条误差：";
    for (double point : checkPoints) {
        Es = abs(spline1.S3(1, df1(-5), df1(5), point) - f(point));
        cout << Es << " ";
    }
    cout << endl;

    return 0;
}